{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 列表 (List)\n",
    "\n",
    "序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置，或索引，第一个索引是0，第二个索引是1，依此类推。\n",
    "\n",
    "Python有6个序列的内置类型，但最常见的是列表和元组。\n",
    "\n",
    "序列都可以进行的操作包括索引，切片，加，乘，检查成员。\n",
    "\n",
    "此外，Python已经内置确定序列的长度以及确定最大和最小的元素的方法。\n",
    "\n",
    "列表是最常用的Python数据类型，它可以作为一个方括号内的逗号分隔值出现。\n",
    "\n",
    "列表的数据项不需要具有相同的类型\n",
    "\n",
    "创建一个列表，只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示：\n",
    "\n",
    "```\n",
    "List are the most basic data structure in Python. Each element in a List is assigned a number - its position, or index, with the first index being 0, the second index being 1, and so on.\n",
    "\n",
    "Python has six built-in types of List, but the most common are lists and tuples.\n",
    "\n",
    "The operations that can all be performed on List include indexing, slicing, adding, multiplying, and checking members.\n",
    "\n",
    "In addition, Python has built-in methods for determining the length of a List and for determining the largest and smallest elements.\n",
    "\n",
    "Lists are the most commonly used Python data type, and can appear as comma-separated values within square brackets.\n",
    "\n",
    "Data items of a list need not have the same type\n",
    "\n",
    "To create a list, simply enclose the different data items separated by commas in square brackets. This is shown below:\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list1 = ['Google', 'Python', 1997, 2000]\n",
    "list2 = [1, 2, 3, 4, 5 ]\n",
    "list3 = [\"'a'\", \"b\", \"c\", \"d\",list2]\n",
    "print(list1,list2,list3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用下标索引来访问列表中的值，同样大家也可以使用方括号的形式截取字符，如下所示：\n",
    "> Use the subscript index to access the values in the list, again one can use the square bracketed form to intercept characters as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list1[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list2[1:4]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 练习1\n",
    "\n",
    "how to get \"3\" from the list?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "my_list1 = [1,2,3,4,5]\n",
    "my_list2 = ['a',-1,0,4]\n",
    "my_list1[-3]\n",
    "print (my_list2[1]+my_list2[-1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 更新列表(update)\n",
    "\n",
    "我们可以对列表的数据项进行修改或更新，我们也可以使用append()方法来添加列表项，如下所示：\n",
    "> We can modify or update the data items of the list, and we can also add list items using the append() method, as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list1 = ['Google', 'Python', 1997, 2000]\n",
    "print(\"the 3rd element : \", list1[2])\n",
    "list1[2] = 2001\n",
    "print(\"After updating, the 3rd element : \", list1[2])\n",
    "list1.append(1)\n",
    "list1\n",
    "list1.append(2)\n",
    "list1.append(3)\n",
    "list1.append(4)\n",
    "list1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 删除列表元素 (delete)\n",
    "可以使用 del 语句来删除列表的的元素，如下实例：\n",
    "> Elements of a list can be deleted using the del statement, as in the following example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list4 = ['Google', 'Python', 1997, 2000] \n",
    "print (\"原始列表 : \", list4)\n",
    "del list4[2]\n",
    "print (\"删除第三个元素 : \", list4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list4 = ['Google', 'Python', 1997, 2000]\n",
    "list4.remove('Google')\n",
    "print (\"删除特定元素 : \", list4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Ex2\n",
    "\n",
    "把列表中不同类删掉，或替换另一种类型\n",
    "> Delete a different class from the list or replace it with another type"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "my_list1 = ['Apple', 'Huawei', 'Lychee', 'Mango', 'Watermelon']\n",
    "my_list2 = ['Apple', 'Huawei', 'Samsung', 'Xiaomi', 'Watermelon']\n",
    "my_list2.remove('Xiaomi')\n",
    "del my_list1[1]\n",
    "my_list1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#-- 常用列表常量和操作，需要逐个运行，这里是展示\n",
    "L = [[1, 2], 'string', {}]                        # 嵌套列表\n",
    "L = list('spam')                                  # 列表初始化 initialisation\n",
    "L = list(range(0, 4))                             # 列表初始化 \n",
    "len(L)                                            # 求列表长度\n",
    "L.count(value)                                    # 求列表中某个值的个数\n",
    "L.append(obj)                                     # 向列表的尾部添加数据，比如append(2)，添加元素2\n",
    "L.insert(index, obj)                              # 向列表的指定index位置添加数据，index及其之后的数据后移\n",
    "L.extend(interable)                               # 通过添加iterable中的元素来扩展列表，比如extend([2])，添加元素2，注意和append的区别\n",
    "L.index(value, [start, [stop]])                   # 返回列表中值value的第一个索引\n",
    "L.pop([index])                                    # 删除并返回index处的元素，默认为删除并返回最后一个元素\n",
    "L.remove(value)                                   # 删除列表中的value值，只删除第一次出现的value的值\n",
    "L.reverse()                                       # 反转列表\n",
    "L.sort(cmp=None, key=None, reverse=False)         # 排序列表\n",
    "a = [1, 2, 3], b = a[10:]                         # 注意，这里不会引发IndexError异常，只会返回一个空的列表[]\n",
    "a = [], a += [1]                                  # 这里实在原有列表的基础上进行操作，即列表的id没有改变\n",
    "a = [], a = a + [1]                               # 这里最后的a要构建一个新的列表，即a的id发生了变化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "L=[1,2,3,4]\n",
    "L.insert(2,5)\n",
    "L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#　L.sort(cmp=None, key=None, reverse=False)         # 排序列表\n",
    "L = [4,5,2,3,1,3,7]\n",
    "L.sort(0,7)\n",
    "print(L)\n",
    "L.reverse()\n",
    "print(L)\n",
    "print(L.count(788))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 列表解析\n",
    "列表解析的语法：[expr for iter_val in iterable] \n",
    "> The syntax of list parsing: [expr for iter_val in iterable]\n",
    "\n",
    "\n",
    "简单说，就是对于一个可迭代的对象中的每一个元素，通过表达式对该元素作用，得到一个计算结果，然后再通过for循环遍历这个可迭代对象的每一个元素，将作用后的结果构成一个列表。这个作用后的结果可能是由之前元素计算得到的新对象，也可能就是原先的元素。\n",
    "> Simply put, for each element of an iterable object, an expression is applied to that element to obtain a computed result, and then each element of the iterable object is iterated through a for loop to form a list. The result of this action may be a new object computed from the previous element, or it may be the original element.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Perform calculations on each value in the sequence in turn\n",
    "a = [1, 2, 3, 4, 5]\n",
    "result = [x ** 2 for x in a] # x is the element and the list a is the iterable\n",
    "print(result) # >>> [1, 4, 9, 16, 25]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = [x + 1 for x in range(10)]\n",
    "print(result) # >>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# the other way\n",
    "result = []\n",
    "for x in range(10):\n",
    "    result.append(x+1)\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Exercise 3\n",
    "\n",
    "Delete the numbers greater than 100 and sort them from small to large"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "L = [6,7,88,191,32,330,12,54,901,104,3,67,111,1479,0]\n",
    "#method 1：\n",
    "for l in L:\n",
    "    if l>100:\n",
    "        L.remove(l)\n",
    "L.sort()\n",
    "L\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 3, 6, 7, 12, 32, 54, 67, 88, 104, 111, 191, 330, 901, 1479]\n",
      "104\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[0, 3, 6, 7, 12, 32, 54, 67, 88]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_list1 = [6,7,88,191,32,330,12,54,901,104,3,67,111,1479,0]\n",
    "my_list1.sort()\n",
    "#method 2：\n",
    "i = 0\n",
    "for l in my_list1:\n",
    "    if l>100:\n",
    "        i = my_list1.index(l)\n",
    "        break\n",
    "print(my_list1)\n",
    "print(my_list1[i])\n",
    "my_list1[:i]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 元组 tuple\n",
    "\n",
    "Python 的元组与列表类似，不同之处在于元组的元素<strong>不能修改</strong>。\n",
    "\n",
    "元组使用小括号，列表使用方括号。\n",
    "\n",
    "元组创建很简单，只需要在括号中添加元素，并使用逗号隔开即可\n",
    "\n",
    "> Python's tuples are similar to lists, except that the elements of the tuple are not modifiable.\n",
    ">\n",
    "> Use parentheses for tuples and square brackets for lists.\n",
    ">\n",
    "> Tuple creation is very simple, just add elements in parentheses and separate them with commas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('Google', 'Python', 1997, 2000, []) (1, 2, 3, 4, 5) ('a', 'b', 'c', 'd')\n",
      "<class 'tuple'>\n"
     ]
    }
   ],
   "source": [
    "tup1 = ('Google', 'Python', 1997, 2000,[]);\n",
    "tup2 = (1, 2, 3, 4, 5 );\n",
    "tup3 = \"a\", \"b\", \"c\", \"d\"   #  do not need ()\n",
    "print(tup1,tup2,tup3)\n",
    "print(type(tup3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tup1[0]:  Google\n",
      "tup2[1:5]:  (2, 3, 4, 5)\n"
     ]
    }
   ],
   "source": [
    "tup1 = ('Google', '[Python]', 1997, 2000)\n",
    "tup2 = (1, 2, 3, 4, 5, 6, 7 )\n",
    " \n",
    "print (\"tup1[0]: \", tup1[0])\n",
    "print (\"tup2[1:5]: \", tup2[1:5])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(12, 34.56, 'abc', 'xyz')\n"
     ]
    }
   ],
   "source": [
    "tup1 = (12, 34.56);\n",
    "tup2 = ('abc', 'xyz')\n",
    " \n",
    "# the use of this language will not work in this circumstances。\n",
    "# tup1[0] = 100\n",
    "\n",
    "# create a new tuple\n",
    "tup3 = tup1 + tup2;\n",
    "print(tup3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('Google', 'Runoob', 1997, 2000)\n",
      "After deletd tuple : \n"
     ]
    },
    {
     "ename": "NameError",
     "evalue": "name 'tup' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-10-1355d186ba6a>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0;32mdel\u001b[0m \u001b[0mtup\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      7\u001b[0m \u001b[0mprint\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m\"After deletd tuple : \"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0mprint\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtup\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name 'tup' is not defined"
     ]
    }
   ],
   "source": [
    "# The element value in the tuple is not allowed to be deleted, \n",
    "# but we can use the del statement to delete the entire tuple, as shown in the following example\n",
    "tup = ('Google', 'Runoob', 1997, 2000)\n",
    " \n",
    "print (tup)\n",
    "del tup\n",
    "print (\"After deletd tuple : \")\n",
    "print (tup)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Ex4\n",
    "\n",
    "Using the tuple for recording the coordinate (1,1),(2,2),(3,3),(4,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 1)\n",
      "(2, 2)\n",
      "(3, 3)\n",
      "(4, 4)\n"
     ]
    }
   ],
   "source": [
    "# use for to print the answer\n",
    "for i in range(4):\n",
    "    print((i+1,i+1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 字典\n",
    "字典是另一种可变容器模型，且可存储任意类型对象。\n",
    "\n",
    "字典的每个键值(key=>value)对用冒号(:)分割，每个对之间用逗号(,)分割，整个字典包括在花括号({})中 ,格式如下所示\n",
    "\n",
    "d = {key1 : value1, key2 : value2 }\n",
    "\n",
    "键必须是唯一的，但值则不必。\n",
    "\n",
    "值可以取任何数据类型，但键必须是不可变的，如字符串，数字或元组。\n",
    "\n",
    "一个简单的字典实例：\n",
    "\n",
    "```\n",
    "dictionary\n",
    "Dictionaries are another mutable container model and can store objects of any type.\n",
    "\n",
    "Each key-value (key=>value) pair of the dictionary is separated by a colon (:), and each pair is separated by a comma (,). The entire dictionary is included in curly braces ({}), and the format is as follows\n",
    "\n",
    "d = {key1: value1, key2: value2}\n",
    "\n",
    "Keys must be unique, but values do not.\n",
    "\n",
    "Values can take any data type, but keys must be immutable like strings, numbers or tuples.\n",
    "\n",
    "A simple dictionary instance:\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict1['Name']:  Andy\n",
      "dict1['Age']:  7\n",
      "{'Name': 'Andy', 'Age': 8, 'Class': 'First', 'School': '魔法学院'}\n",
      "dict1['Age']:  8\n",
      "dict1['School']:  魔法学院\n",
      "0\n"
     ]
    }
   ],
   "source": [
    "# choose the right key:\n",
    "dict1 = {'Name': 'Andy', 'Age': 7, 'Class': 'First'}\n",
    " \n",
    "print (\"dict1['Name']: \", dict1['Name'])\n",
    "print (\"dict1['Age']: \", dict1['Age'])\n",
    "\n",
    "dict1['Age'] = 8               # update Age\n",
    "dict1['School'] = \"魔法学院\"   # add more key\n",
    "print(dict1)\n",
    "\n",
    "print (\"dict1['Age']: \", dict1['Age'])\n",
    "print (\"dict1['School']: \", dict1['School'])\n",
    "print(dict1.get(\"age\", 0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# -- 常用字典常量和操作，这里不能直接运行\n",
    "D = {}\n",
    "D = {'spam':2, 'tol':{'ham':1}}                   # 嵌套字典\n",
    "D = dict.fromkeys(['s', 'd'], 8)                  # {'s': 8, 'd': 8}\n",
    "D = dict(name = 'tom', age = 12)                  # {'age': 12, 'name': 'tom'}\n",
    "D = dict([('name', 'tom'), ('age', 12)])          # {'age': 12, 'name': 'tom'}\n",
    "D = dict(zip(['name', 'age'], ['tom', 12]))       # {'age': 12, 'name': 'tom'}\n",
    "D.keys(); D.values(); D.items()                   # 字典键、值以及键值对\n",
    "D.get(key, default)                               # get函数\n",
    "D.update(D_other)                                 # 合并字典，如果存在相同的键值，D_other的数据会覆盖掉D的数据\n",
    "D.pop(key, [D])                                   # 删除字典中键值为key的项，返回键值为key的值，如果不存在，返回默认值D，否则异常\n",
    "D.popitem()                                       # pop字典中随机的一项（一个键值对）\n",
    "del D                                             # 删除字典\n",
    "del D['key']                                      # 删除字典的某一项\n",
    "if key in D:   if key not in D:                   # 测试字典键是否存在\n",
    "# 字典注意事项：（1）对新索引赋值会添加一项（2）字典键不一定非得是字符串，也可以为任何的不可变对象\n",
    "# 不可变对象：调用对象自身的任意方法，也不会改变该对象自身的内容，这些方法会创建新的对象并返回。\n",
    "# 字符串、整数、tuple都是不可变对象，dict、set、list都是可变对象\n",
    "D[(1,2,3)] = 2                                    # tuple作为字典的key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# 尝试一下\n",
    "D = {'spam':2, 'tol':{'ham':1}}  \n",
    "print(D)\n",
    "D_other = {'update':'new value'}\n",
    "D.update(D_other)\n",
    "print(D)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Ex5\n",
    "\n",
    "print out the age value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "12\n"
     ]
    }
   ],
   "source": [
    "student = {'名字':'莱克', 'age':'12', '班级':'201', '性别':'男'}\n",
    "print(student['age'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Ex6\n",
    "\n",
    "新学期开始，需要更新所有学生的年龄，所有人年龄都加一岁。\n",
    "> At the beginning of the new semester, the ages of all students need to be updated, and the ages of all students should be increased by one year."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "list indices must be integers or slices, not str",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-49-c3cdf6596c24>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      6\u001b[0m ] \n\u001b[1;32m      7\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mstudent\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mstudent_list\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m     \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstudent_list\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      9\u001b[0m     \u001b[0mstudent\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mint\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mstudent_list\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     10\u001b[0m     \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstudent_list\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mTypeError\u001b[0m: list indices must be integers or slices, not str"
     ]
    }
   ],
   "source": [
    "student_list=[\n",
    "    {'name':'May', 'age':'12', 'class':'201', 'gen':'男'},\n",
    "    {'name':'Louis', 'age':'12', 'class':'202', 'gen':'女'},\n",
    "    {'name':'Jay', 'age':'12', 'class':'202', 'gen':'女'},\n",
    "    {'name':'Mark', 'age':'12', 'class':'201', 'gen':'男'},\n",
    "] \n",
    "for student in student_list:\n",
    "    print(student_list['age'])\n",
    "    student['age'] = int (student_list['age']) + 1   \n",
    "    print(student_list)\n",
    "# print(student_list)2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}\n",
    "print(basket)                      # 这里演示的是去重功能"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#-- 集合set，不能直接运行\n",
    "\"\"\"\n",
    "set是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素。\n",
    "set支持union(联合), intersection(交), difference(差)和symmetric difference(对称差集)等数学运算。\n",
    "set支持x in set, len(set), for x in set。\n",
    "set不记录元素位置或者插入点, 因此不支持indexing, slicing, 或其它类序列的操作\n",
    "\"\"\"\n",
    "s = set([3,5,9,10])                          # 创建一个数值集合，返回{3, 5, 9, 10}\n",
    "t = set(\"Hello\")                             # 创建一个字符的集合，返回{'l', 'H', 'e', 'o'}\n",
    "a = t | s;    t.union(s)                     # t 和 s的并集\n",
    "b = t & s;    t.intersection(s)              # t 和 s的交集\n",
    "c = t - s;  t.difference(s)                # 求差集（项在t中, 但不在s中）\n",
    "d = t ^ s;    t.symmetric_difference(s)      # 对称差集（项在t或s中, 但不会同时出现在二者中）\n",
    "t.add('x');   t.remove('H')                  # 增加/删除一个item\n",
    "s.update([10,37,42])                         # 利用[......]更新s集合\n",
    "'x' in s,  'x' not in s                          # 集合中是否存在某个值\n",
    "s.issubset(t);      s <= t                   # 测试是否 s 中的每一个元素都在 t 中\n",
    "s.issuperset(t);    s >= t                   # 测试是否 t 中的每一个元素都在 s 中 \n",
    "s.copy(); \n",
    "s.discard('x');                                # 删除s中x\n",
    "s.clear()                                    # 清空s\n",
    "{x**2 for x in [1, 2, 3, 4]}                 # 集合解析，结果：{16, 1, 4, 9}\n",
    "{x for x in 'spam'}                          # 集合解析，结果：{'a', 'p', 's', 'm'}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "set([3,3,5,9,10]) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 尝试一下\n",
    "a = set(\"Hello\")\n",
    "b = set(\"Happy\")  \n",
    "print(a | b)\n",
    "print(a - b)\n",
    "a.add('x')\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  练习7\n",
    "\n",
    "题目：求s=a+aa+aaa+aaaa+aa...a的值，其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "n = int(input('有多少个数'))\n",
    "a = input('a代表数字是？')\n",
    "sn = [] # 记录相加的数字,sn = sum of number\n",
    "\n",
    "for count in range(?, ?):  #count 数数\n",
    "    tmp_a = a*count   #tmp = template 临时\n",
    "    ? # your code\n",
    "print(sn)\n",
    "print('+'.join([str(s)for s in sn])) # 输出算式，（可以不写）.join字符串专用\n",
    "# Sn 求和\n",
    "sum(sn)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 扩展知识\n",
    "\n",
    "collections是Python内建的一个集合模块，提供了许多有用的集合类。\n",
    "\n",
    "1. namedtuple\n",
    "2. deque\n",
    "3. defaultdict\n",
    "4. OrderedDict\n",
    "5. Counter\n",
    "\n",
    "更多解释，我们可以网上找一下用法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### namedtuple\n",
    "\n",
    "它用来创建一个自定义的tuple对象，并且规定了tuple元素的个数，并可以用属性而不是索引来引用tuple的某个元素。\n",
    "\n",
    "这样一来，我们用namedtuple可以很方便地定义一种数据类型，它具备tuple的不变性，又可以根据属性来引用，使用十分方便。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 集合\n",
    "集合（set）是一个<strong>无序不重复元素</strong>的序列。\n",
    "\n",
    "可以使用大括号 { } 或者 set() 函数创建集合，注意：创建一个空集合必须用 set() 而不是 { }，因为 { } 是用来创建一个空字典。\n",
    "\n",
    "创建格式："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import namedtuple\n",
    "Point = namedtuple('Point', ['x', 'y'])\n",
    "p = Point(1, 2)  #nametuple的作用：让元组像字典一样，能带键值表示，不用索引\n",
    "print(p.x, p.y)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### deque\n",
    "使用list存储数据时，按索引访问元素很快，但是插入和删除元素就很慢了，因为list是线性存储，数据量大的时候，插入和删除效率很低。\n",
    "\n",
    "deque是为了高效实现插入和删除操作的双向列表，适合用于队列和栈："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import deque\n",
    "q = deque(['a', 'b', 'c'])\n",
    "q.append('x')\n",
    "q.appendleft('y')\n",
    "print(q)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### defaultdict\n",
    "使用dict时，如果引用的Key不存在，就会抛出KeyError。如果希望key不存在时，返回一个默认值，就可以用defaultdict："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import defaultdict\n",
    "dd = defaultdict(list)\n",
    "dd['key1'] = 'abc'\n",
    "print(dd['key1']) # key1存在\n",
    "print(dd['key2']) # key2不存在，返回默认值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### OrderedDict\n",
    "使用dict时，Key是无序的。在对dict做迭代时，我们无法确定Key的顺序。\n",
    "\n",
    "如果要保持Key的顺序，可以用OrderedDict："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import OrderedDict\n",
    "d = {'a': 1, 'b': 2, 'c': 3}\n",
    "print('无序的', d) # dict的Key是无序的\n",
    "od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])\n",
    "print(od)\n",
    "od.move_to_end('a')\n",
    "print(od)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "默认情况下Python的字典输出顺序是按照键的按创建顺序。\n",
    "\n",
    "字典的无序是指，不能人为重新排序。\n",
    "\n",
    "比如说你按键值1，2，3，4的顺序创建的字典，只能由解析器按创建顺序，还是1，2，3，4的输出。\n",
    "\n",
    "你无法控制它按照，4，3，2，1的顺序输出，你也无法做到，1，3，2，4的顺序。\n",
    "\n",
    "而且这个输出顺序是也不是能真正按照创建顺序可以控的。\n",
    "\n",
    "这里面有两个影响因素：\n",
    "\n",
    "（1）键值的哈希碰撞，hash(key1) == hash(key2)时，向字典里连续添加的这两个键的顺序是不可以控制的，也是无法做到连续的，后来的键会按算法调整到其它位置\n",
    "\n",
    "（2）字典空间扩容，当键的数量超过字典默认开的空间时，字典会做空间扩容，扩容后的键顺和创建顺序就会发生变化，不受人为控制"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Counter\n",
    "Counter是一个简单的计数器，例如，统计字符出现的个数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import Counter  #说明要使用这个函数，这个函数不是默认就能用，collection是一个代码库\n",
    "c = Counter()   #Counter()是对象，后面会详细说\n",
    "for ch in 'programming':  #用for循环遍历整个字符串\n",
    "    c[ch] = c[ch] + 1\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# other way:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 练习"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Find all the elements that start with A or a and end with c.\n",
    "li = ['alec','aric','Alex',' Tony','rain']\n",
    "tu = ('alec','aric','Alex',' Tony','rain')\n",
    "dic = {'k1':'alex','k2':'aric','k3':'Alex','k4':'Tony'}\n",
    "\n",
    "for val in li:\n",
    "    val = val.lower()\n",
    "    if val.startswith('a') and val.endswith('c'):  #startswith 和 endswith 是字符串自带的固定写法\n",
    "        print(val, end=',')\n",
    "        \n",
    "print('\\n----------------------------------')\n",
    "\n",
    "for val in tu:\n",
    "    ？？？\n",
    "    ？？？\n",
    "    ？？？\n",
    "        \n",
    "print('\\n----------------------------------')\n",
    "\n",
    "for val in dic.values():\n",
    "    ？？？\n",
    "    ？？？\n",
    "    ？？？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "states = { '广东': '粤',\n",
    "    '福建': '闽',\n",
    "    '湖北': '鄂',}\n",
    "\n",
    "cities = {'粤': '佛山',\n",
    "    '鄂': '武汉',}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "添加城市 闽：厦门"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 解答\n",
    "cities['闽'] = '厦门'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "打印所有states"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for key, val in states.items():\n",
    "    print(key + \":\" + val)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "打印所有cities"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for key, val in ???():\n",
    "    print(key + \":\" + val)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " 打印所有states，以及states 包含的cities"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for key, val in states.items():\n",
    "    print(key + \":\" + val)\n",
    "\n",
    "    if val in cities.keys():\n",
    "        print(\"     |-\",cities[val])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cities.keys()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
